package pers.jason.wppm.security.core.authentication.mobile;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;

/**
 * 
 * @author Jason
 * @Date 2018-11-09 16:12
 *
 */
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	private boolean postOnly = true;

	private String mobileParameterName;

	public SmsCodeAuthenticationFilter(String mobileParameterName, String mobileLoginUrl) {
		super(new AntPathRequestMatcher(mobileLoginUrl, "POST"));
		this.mobileParameterName = mobileParameterName;
	}
	
	

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {
		// TODO Auto-generated method stub
		if(postOnly && !(request.getMethod().equals("POST"))) {
			throw new AuthenticationServiceException(
					"Authentication method not supported: " + request.getMethod());
		}
		
		String mobile = request.getParameter(mobileParameterName);
		mobile = (null == mobile) ? "" : mobile.trim();
		
		
		//获取一个未校验的token
		SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile);
		
		setDetails(request, authRequest);
		
		return this.getAuthenticationManager().authenticate(authRequest);
	}
	
	

	/**
	 * 将请求信息也放入token中
	 * @param request
	 * @param authRequest
	 */
	protected void setDetails(HttpServletRequest request,
			SmsCodeAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}

	/**
	 * Sets the parameter name which will be used to obtain the mobile from the login
	 * request.
	 *
	 * @param usernameParameter the parameter name. Defaults to "username".
	 */
	public void setMobileParameter(String mobile) {
		Assert.hasText(mobile, "Username parameter must not be empty or null");
		this.mobileParameterName = mobile;
	}

	public String getMobileParameterName() {
		return mobileParameterName;
	}

	/**
	 * Defines whether only HTTP POST requests will be allowed by this filter. If set to
	 * true, and an authentication request is received which is not a POST request, an
	 * exception will be raised immediately and authentication will not be attempted. The
	 * <tt>unsuccessfulAuthentication()</tt> method will be called as if handling a failed
	 * authentication.
	 * <p>
	 * Defaults to <tt>true</tt> but may be overridden by subclasses.
	 */
	public void setPostOnly(boolean postOnly) {
		this.postOnly = postOnly;
	}



}
